package cn.genmer.test.security.jackcess;

import java.io.*;

import cn.genmer.test.security.model.MINING_APPLY;
import com.alibaba.fastjson.JSON;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.Table;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * 解析MDB文件
 * @author： cp
 * @date： 2021-02-18 09:12
 */

public class AccessParseUtils {

/**
     * 读取解析access文件
     * @param mdbFile
     * @return
     */

    @SuppressWarnings({"unchecked"})
    public static List<Map> readFileACCESS(File mdbFile) {
        List<Map> maplist = new ArrayList();
//        File mdbFile = new File(filePath);
        try {
            if (mdbFile.exists()) {
                Database dbin = null;
//                dbin = Database.open(mdbFile);//读文件
                dbin = DatabaseBuilder.open(mdbFile);
                Set<String> tables = dbin.getTableNames();

                for (String t : tables) {//遍历所有表名
                    Map mapTable = new HashMap();
                    mapTable.put("tableName", t);
                    Table table = dbin.getTable(t); //获取对应表结构
                    List<Map> list = new ArrayList();
                    for (Map<String, Object> map : table) {//遍历表数据
                        list.add(map);
                    }
                    mapTable.put("data", list);
                    maplist.add(mapTable);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return maplist;
    }

    /**
     * 读取解析access文件 - MultipartFile
     * @param multipartFile
     * @return
     */
    @SuppressWarnings({"unchecked"})
    public static List<Map> readFileACCESS(MultipartFile multipartFile) throws IOException {
        // MultipartFile 转为File
        File mdbFile =null;
        mdbFile =  transferToFile(multipartFile);


        List<Map> maplist = new ArrayList();
//        File mdbFile = new File(filePath);
        try {
            if (mdbFile.exists()) {
                Database dbin = null;
//                dbin = Database.open(mdbFile);//读文件
                dbin = DatabaseBuilder.open(mdbFile);
                Set<String> tables = dbin.getTableNames();

                for (String t : tables) {//遍历所有表名
                    Map mapTable = new HashMap();
                    mapTable.put("tableName", t);
                    Table table = dbin.getTable(t); //获取对应表结构
                    List<Map> list = new ArrayList();
                    for (Map<String, Object> map : table) {//遍历表数据
                        list.add(map);
                    }
                    mapTable.put("data", list);
                    maplist.add(mapTable);
                }
                dbin.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 删除缓存文件
        File del = new File(mdbFile.toURI());
        del.delete();
        return maplist;
    }

    /**
     * 测试
     * @param args
     */
    @SuppressWarnings("static-access")
    public static void main(String[] args) {
        AccessParseUtils rmf = new AccessParseUtils();
        File mdbFile = new File("D:\\geocloud\\mdbdownloads\\a686adcf-02d5-4d26-b669-7014cfcb4b7e.mdb");
        List<Map> maps = rmf.readFileACCESS(mdbFile);
        Map data = (Map) maps.get(0);
        String tableName = data.get("tableName").toString();

        List<Map> mapList = (List) data.get("data");
        Map map = mapList.get(0);
        MINING_APPLY apply = JSON.parseObject(JSON.toJSONString(map), MINING_APPLY.class);
        System.out.println();
    }

    /**
     * Map转成实体对象
     * @param map map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();

            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                field.set(obj, map.get(field.getName()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }


    /**
     * file 转换为 MultipartFile
     * @param file
     * @return
     * @throws IOException
     */
    private static File transferToFile(MultipartFile file) throws IOException {
        File f = null;
        if(file.equals("")||file.getSize()<=0){
            file = null;
        }else{
            InputStream ins = file.getInputStream();
            f=new File(file.getOriginalFilename());
            inputStreamToFile(ins, f);
        }
        return f;
    }

    /**
     * 通过流写入文件
     * @param ins
     * @param file
     */
    public static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}